package com.ebupt.migu.music.strategy.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ebupt.migu.music.common.auth.AuthBaseUtils;
import com.ebupt.migu.music.common.auth.IDAuthUtils;
import com.ebupt.migu.music.common.entity.ResultObject;
import com.ebupt.migu.music.common.exception.MyException;
import com.ebupt.migu.music.common.exception.StatusEnum;
import com.ebupt.migu.music.common.util.CSVUtils;
import com.ebupt.migu.music.common.util.DateUtil;
import com.ebupt.migu.music.common.util.ReqestParamUtil;
import com.ebupt.migu.music.strategy.entity.SMSApproveRankInfoBean;
import com.ebupt.migu.music.strategy.service.StrategyService;
import com.ebupt.migu.music.system.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;

/**
 * Created by Intellij IDEA.
 * User:  liuyangyang@cd.ebupt.com
 * Date:  2019/9/24
 */
@Slf4j
@RestController
@RequestMapping("/strategy")
public class StrategyController {

    @Autowired
    private HttpServletRequest request;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StrategyService strategyService;
    @Autowired
    private IDAuthUtils idAuthUtils;
    @Value("${path.push_image_path}")
    private String pushImagePath;


    /**
     * 创建策略
     *
     * @return
     */
    @PostMapping("/add")
    public ResultObject add(@RequestBody List<Object> paramList) {
        log.info(">>>>>>>>>>>>>>params：{}", JSON.toJSONString(paramList));
        // 获取用户信息和业务参数
        Map<String, Object> paramMap = AuthBaseUtils.authBaseInfo(paramList, request);
        try {
            return strategyService.addStrategy(paramMap);
        } catch (MyException e) {
            ResultObject res = new ResultObject();
            res.setCode(e.getStatusEnum().getCode());
            res.setMsg(e.getMessage());
            return res;
        }
    }

    /**
     * 分页、条件查询策略列表
     * 查询条件： 策略名称、策略类型、创建时间、执行状态、创建人、
     *
     * @return
     */
    @PostMapping("/list")
    public ResultObject strategyList() {
        // 获取用户登录信息
        SysUser user = AuthBaseUtils.getSessionUser(request);
        Map<String, Object> params = ReqestParamUtil.getParams(request);
        return strategyService.strategyList(params, user);
    }

    /**
     * 分页、条件查询策略列表
     * 查询条件： 策略名称、策略类型、创建时间、执行状态、创建人、部门
     *
     * @return
     */
    @PostMapping("/listByNameOrId")
    public ResultObject listByNameOrId() {
        // 获取用户登录信息
        SysUser user = AuthBaseUtils.getSessionUser(request);
        Map<String, Object> params = ReqestParamUtil.getParams(request);
        return strategyService.strategyListByNameOrId(params, user);
    }

    /**
     * 删除策略
     *
     * @return
     */
    @PostMapping("/delete")
    public ResultObject deleteStrategy() {
        // 验证用户是否有此操作权限
        if (!idAuthUtils.isCreatorOrAdmin(request)) {
            throw new MyException(StatusEnum.OPERATE_LIMITED, "用户无权删除此人群");
        }
        Map<String, Object> params = ReqestParamUtil.getParams(request);
        return strategyService.deleteStrategy(params);
    }

    /**
     * 修改策略详情
     * 1. 谁创建、谁修改、谁删除...
     *
     * @return
     */
    @PostMapping("/update")
    public ResultObject updateStrategy(@RequestBody Map paramMap) {
        if (null == paramMap || null == paramMap.get("creatorId")) {
            throw new MyException(StatusEnum.BUSINID, "访问参数异常");
        }
        // 验证用户是否有此操作权限
        if (!idAuthUtils.isCreatorOrAdmin(paramMap, request)) {
            throw new MyException(StatusEnum.OPERATE_LIMITED, "用户无权更新此人群");
        }
        Map<String, Object> params = ReqestParamUtil.getParamsWithUserInfo(paramMap, request);
        return strategyService.updateStrategy(params);
    }

    /**
     * 中止/终止策略执行
     *
     * @return
     */
    @PostMapping("/end")
    public ResultObject endExecute() {
        // 验证用户是否有此操作权限
        if (!idAuthUtils.isCreatorOrAdmin(request)) {
            throw new MyException(StatusEnum.OPERATE_LIMITED, "用户无权中止此人群");
        }
        Map<String, Object> params = ReqestParamUtil.getParams(request);
        return strategyService.endExecute(params);
    }

    /**
     * 重新提交运营策略：
     * 1. 验证当前用户是否超级管理员或者运营策略创建者
     * 2. 验证重新提交的运营策略人群是否超过200人：超过200- 执行状态修改为待审核；未超过200- 执行状态修改为未开始；
     *
     * @return
     */
    @PostMapping("/resubmit")
    public ResultObject resubmit() {
        // 验证用户是否有此操作权限
        if (!idAuthUtils.isCreatorOrAdmin(request)) {
            throw new MyException(StatusEnum.OPERATE_LIMITED, "用户无权重新提交此人群");
        }
        Map<String, Object> params = ReqestParamUtil.getParams(request);
        return strategyService.resubmit(params);
    }

    /**
     * 消息推送--上传图片
     *
     * @return
     */
    @RequestMapping(value = "/imageUpload")
    public ResultObject imageUpload(@RequestParam("file") MultipartFile file) {
        ResultObject res = new ResultObject();
        Date date = new Date();
        String timeStr = DateUtil.parseDateToStr(date, DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISS);
        String newPath = pushImagePath + timeStr + "_" + file.getOriginalFilename();
        log.info("图片上传路径及重命名：{}", newPath);
        //上传图片到指定目录
        CSVUtils.upload(file, newPath);
        Map<String, Object> retMap = new HashMap<String, Object>();
        retMap.put("oriName", file.getOriginalFilename());
        retMap.put("reName", timeStr + "_" + file.getOriginalFilename());
        retMap.put("filePath", newPath);
        res.setData(retMap);
        res.setMsg("上传图片成功");
        return res;
    }

    /**
     * 消息推送--图片删除
     *
     * @return
     */
    @RequestMapping(value = "/imageDel")
    public ResultObject imageDel() {
        ResultObject res = new ResultObject();
        Map<String, Object> paramMap = ReqestParamUtil.getParams(request);
        String path = paramMap.get("filePath").toString();
        File file = new File(path);
        if (file.exists()) {
            file.delete();
        }
        res.setMsg("删除图片成功");
        return res;
    }

    /**
     * 查询策略详情
     * i 策略审批查看策略详情
     * ii 查看策略关联的人群的详情
     *
     * @return
     */
    @PostMapping("/detail")
    public ResultObject detail() {
        Map<String, Object> params = ReqestParamUtil.getParams(request);
        return strategyService.detail(params);
    }

    /**
     * 手动输入短信接受人，测试短息您发送
     *
     * @return
     */
    @PostMapping("/sendMsgForTest")
    public ResultObject sendMsgForTest() {
        Map<String, Object> params = ReqestParamUtil.getParams(request);
        return strategyService.sendMsgForTest(params);
    }

    /**
     * 实时查询短信下发进度
     *
     * @return
     */
    @PostMapping("/sms_progress")
    public ResultObject sms_progress() {
        ResultObject res = new ResultObject();
        List<HashMap<String, Object>> datas = new ArrayList<>();
        Map<String, Object> params = ReqestParamUtil.getParams(request);
        // 批量查询短信策略实时进度
        String[] sids = params.get("sids").toString().split(",");
        for (String sid : sids) {
            HashMap<String, Object> data = new HashMap<>();
            String key_name = sid + "_incr";
            // Redis中不存在指定key，返回-1
            if (!redisTemplate.hasKey(key_name)) {
                data.put("progress", "-1");
            } else {
                data.put("progress", redisTemplate.opsForValue().get(key_name));
            }
            datas.add(data);
        }
        res.setCode(StatusEnum.SUCCESS.getCode());
        res.setMsg(StatusEnum.SUCCESS.getMsg());
        res.setData(datas);
        return res;
    }

    /**
     * 通过策略名称查询策略详情
     *
     * @return
     */
    @PostMapping("/queryStrategyDetailByName")
    public ResultObject queryStrategyDetailByName() {
        Map<String, Object> params = ReqestParamUtil.getParams(request);
        return strategyService.queryStrategyDetailByName(params);
    }

    /**
     * 中止/终止策略执行
     *
     * @return
     */
    @PostMapping("/pause")
    public ResultObject pause() {
        // 验证用户是否有此操作权限
        if (!idAuthUtils.isCreatorOrApproverOrAdmin(request)) {
            throw new MyException(StatusEnum.OPERATE_LIMITED, "用户无权操作此人群");
        }
        Map<String, Object> params = ReqestParamUtil.getParams(request);
        return strategyService.pause(params);
    }

    /**
     * 导入用户兑换码
     */
    @PostMapping("/import-user")
    public ResultObject importUser(MultipartFile file, String groupId) {
        return strategyService.pull(file, groupId);
    }

    /**
     * 撤回策略
     * <br>
     * 在创建策略后审批前，提供撤回策略选项，撤回后将策略状态改为待提审
     *
     * @return
     */
    @PostMapping("/revocation")
    public ResultObject<String> revocation() {
        // 验证登录账号是否能执行该操作
        if (!idAuthUtils.isCreatorOrAdminOrAuditor(request)) {
            throw new MyException(StatusEnum.OPERATE_LIMITED, "用户无权撤回此策略");
        }
        return strategyService.revocation(ReqestParamUtil.getParamsWithUserInfo(request));
    }

    /**
     * 与大营销平台同步策略，主要用于联调
     *
     * @param params
     */
    @PostMapping("/sendToMegamarketAudit")
    public void sendToMegamarketAudit(@RequestBody Map<String, Object> params) {
        try {
            strategyService.sendToMegamarketAudit(params);
        } catch (Exception e) {
            log.error("调用大营销平台接口出错", e);
        }
    }

    @PostMapping("/test")
    public void test(@RequestBody Map<String, Object> paramItem) {
        List<SMSApproveRankInfoBean> ranks = JSONObject.parseArray(String.valueOf(paramItem.get("ranks")), SMSApproveRankInfoBean.class);
        for (SMSApproveRankInfoBean rank : ranks) {
            rank.setActivityId("xxx");
            // 1号审核人默认为首位审核人，审核状态默认为审核中
            if ("1".equals(String.valueOf(rank.getRank()))) {
                rank.setStatus(Byte.valueOf("1").byteValue());
                paramItem.put("approverId", String.valueOf(rank.getApproverId()));
                System.out.println(rank.getActivityId());
                paramItem.put("approverName", String.valueOf(rank.getApproverName()));
            }
        }
    }
}